home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Libraries / grayimage / write_pgm.cc < prev    next >
Encoding:
Text File  |  1994-06-30  |  4.8 KB  |  173 lines  |  [TEXT/R*ch]

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /*
  3.  ************************************************************************
  4.  *
  5.  *               Grayscale Image
  6.  *
  7.  *    Write the image into the file in the  Portable GrayMap (pgm) format
  8.  * 
  9.  * The program writes a "binary" (RAWBITS) pgm file of the following format
  10.  *   - A "magic number" for identifying the file type.  A pgm
  11.  *     file's RAWBITS magic number is the two characters "P5".
  12.  *   - Whitespace (blanks, TABs, CRs, LFs).
  13.  *   - A width, formatted as ASCII characters in decimal.
  14.  *   - Whitespace.
  15.  *   - A height, again in ASCII decimal.
  16.  *   - Whitespace.
  17.  *   - The maximum gray value, again in ASCII decimal. For RAWBITS pgm file
  18.  *       the maximum grayscale value cannot exceed 255.
  19.  *   - A _single_ character of whitespace (typically a newline).
  20.  *   - Width * height gray values, each as plain bytes, between
  21.  *     0 and the specified maximum value, stored consecutivly, 
  22.  *     starting at the top-left corner of the graymap, proceding in normal
  23.  *     English reading order. 
  24.  *     A value of 0 means black, and the maximum value means white.
  25.  *
  26.  * For more detail, see documentation on PBMPLUS package (specifically,
  27.  * pgm(5)).
  28.  *
  29.  * $Id: write_pgm.cc,v 1.1 1994/01/12 20:57:02 oleg Exp oleg $
  30.  *
  31.  ************************************************************************
  32.  */
  33.  
  34. #include "image.h"
  35. #include "endian_io.h"
  36.  
  37. #include <iostream.h>
  38.  
  39. #pragma implementation
  40.  
  41. /*
  42.  *------------------------------------------------------------------------
  43.  *               Class PGMFile
  44.  *     designed to contain the control info about the image
  45.  *        as defined in the Portable GrayMap file 
  46.  */
  47.  
  48. class PGMWFile : public EndianIO
  49. {
  50. friend class IMAGE;
  51.  
  52. private:
  53.   int pixmap_width;            // Dimensions of the graymap
  54.   int pixmap_height;
  55.   int max_gray_value;            // Maximum value of a graymap pixel
  56.  
  57.   const IMAGE& image;            // Image being processed
  58.   const char * title;            // Title for the image in the file
  59.  
  60.   void write_image_data();
  61.  
  62. public:
  63.   PGMWFile(const IMAGE& _image);    // Constructor
  64.   ~PGMWFile()    {}            // Destructor
  65.   void set_title(const char * user_title);
  66.   void write_image(const char * file_name);
  67. };
  68.  
  69. /*
  70.  *------------------------------------------------------------------------
  71.  *            Construct the PGMWFile
  72.  *   by filling out the fields of the structure from the IMAGE 
  73.  */
  74.  
  75. PGMWFile::PGMWFile(const IMAGE& _image) : image(_image)
  76. {
  77.   assure(image.q_depth() <= 8,
  78.      "Sorry, the program cannot write images with depth > 8");
  79.  
  80.   pixmap_width = image.q_ncols();
  81.   pixmap_height = image.q_nrows();
  82.   max_gray_value = (1<<image.q_depth())-1;
  83.   title = image.q_name();
  84. }
  85.  
  86. /*
  87.  *------------------------------------------------------------------------
  88.  *            Set up the title for the image
  89.  * image.name == "" && user title == ""  ---> resulting title = ""
  90.  * image.name != "" && user title == ""  ---> resulting title = image.name
  91.  * image.name == "" && user title != ""  ---> resulting title = user title
  92.  * image.name != "" && user title != ""  ---> 
  93.  *            resulting title = "image name/user title"
  94.  *
  95.  * Note that XWdump::title has been already set to image.title.
  96.  * If it is changed, the XWdump::header_size should be modified as well
  97.  */
  98.  
  99. void PGMWFile::set_title(const char * user_title)
  100. {
  101.   if( strlen(user_title) == 0 )
  102.     return;
  103.  
  104.   register int old_title_len = strlen(title);
  105.   
  106.   if( strlen(title) == 0 )        // No image title
  107.     title = user_title;
  108.   else
  109.     title = 
  110.      strcat(
  111.       strcat(
  112.        strcpy((char *)calloc(strlen(title)+1+strlen(user_title)+1,sizeof(char)),title),
  113.        "/"),
  114.       user_title);
  115. }
  116.  
  117. /*
  118.  *------------------------------------------------------------------------
  119.  *               Writing the Portable GrayMap
  120.  */
  121.  
  122. void PGMWFile::write_image(const char * file_name)
  123. {
  124.   
  125.   fstream::open(file_name,ios::out);
  126.                       // Writing the header
  127.   
  128.   char buffer[80];
  129.   sprintf(buffer,"P5\n%d %d\n%d\n",pixmap_width,pixmap_height,max_gray_value);
  130.   
  131.   register char * p;            // This poor thing is because of
  132.   for(p=&buffer[0]; *p != '\0'; p++)    // buggy Think C++
  133.     write_byte(*p);
  134.     
  135.   write_image_data();
  136.   
  137.   close();
  138. }
  139.  
  140.  
  141. /*
  142.  *------------------------------------------------------------------------
  143.  *            Write out the pixel matrix 
  144.  *          with 'bits_per_pixel'representation
  145.  */
  146.  
  147. void PGMWFile::write_image_data()
  148. {
  149.   assert( max_gray_value < 256 );
  150.   
  151.   register int row, col;
  152.   for( row = 0; row < pixmap_height; ++row )
  153.     for( col = 0; col < pixmap_width; ++col )
  154.       write_byte( image(row,col) );
  155. }
  156.  
  157.  
  158. /*
  159.  *------------------------------------------------------------------------
  160.  *                   Root modules 
  161.  *        for writing the image and displaying it
  162.  */
  163.  
  164. void IMAGE::write_pgm(const char * file_name,const char * title) const
  165. {
  166.   is_valid();
  167.  
  168.   message("\nPreparing a PGM file with name '%s'\n",file_name);
  169.   PGMWFile pgmfile(*this);
  170.   pgmfile.set_title(title);
  171.   pgmfile.write_image(file_name);
  172. }
  173.